import string
import os
import time
import types
import socket
import cPickle
import hashlib
import random

from bsddb3 import db

import jsonpickle

try:
	import json
except ImportError:
	import simplejson as json

import config
import constants
import entities

from octopusdbm.client import Dbm

"""
    Copyright (C) 2009,2010  Jorge Alegre Vilches

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.    
"""

class Cloud(object):
	def __init__(self):
		"""Doc."""
		pass
	def registerHost(self, sApp, sHost, sType):
		"""Register host with application and type either processor or db processor. Sets Status code 200.
		@param sApp : String: Application, being any string
		@param sHost: String : Host
		@param sType : String : Type of server: processor or data processor"""
		if sType == constants.TYPE_PROCESSOR:
			tuple = config.MappingHostTuple
		elif sType == constants.TYPE_DB_PROCESOR:
			tuple = config.MappingDbHostTuple
		for sHostMap in tuple:
			print 'HostMap =>', sHostMap
			dbm = Dbm(sHostMap, config.OctopusDict['user'], config.OctopusDict['password'], config.OctopusDict['environment'])
			if sType == constants.TYPE_PROCESSOR:
				table = constants.TABLE_MAP_HOSTS
			elif sType == constants.TYPE_DB_PROCESOR:
				table = constants.TABLE_MAP_DB_HOSTS
			dbm.set_flags(db.DB_DUP)
			dbm.open(table, db.DB_CREATE, db.DB_BTREE, sMode='w')
			c = dbm.cursor()
			appTuple = c.set(sApp)
			bPut = False
			if appTuple:
				while appTuple:
					sApp, sData = appTuple
					sHostTarget, iStatus = json.loads(sData)
					if sHost == sHostTarget:
						tupleNew = (sHost, constants.STATUS_UP)
						c.put(sApp, json.dumps(tupleNew), db.DB_CURRENT)
						bPut = True
					appTuple = c.next_dup()
			if not bPut:
				dataTuple = (sHost, constants.STATUS_UP)
				sData = json.dumps(dataTuple)
				dbm.put(sApp, sData)
			c.close()
			dbm.close()
	def unregisterHost(self, sApp, sHost, sType):
		"""Unregister host with application, setting a status code of 500. When unregistered no connections will
		be sent to this host.
		@param sApp : String : Application
		@param sHost: String : Host
		@param sType : String : Type of host, processor or data processor"""
		if sType == constants.TYPE_PROCESSOR:
			tuple = config.MappingHostTuple
		elif sType == constants.TYPE_DB_PROCESOR:
			tuple = config.MappingDbHostTuple
		for sHostMap in tuple:
			print 'HostMap =>', sHostMap
			dbm = Dbm(sHostMap, config.OctopusDict['user'], config.OctopusDict['password'], config.OctopusDict['environment'])
			if sType == constants.TYPE_PROCESSOR:
				table = constants.TABLE_MAP_HOSTS
			elif sType == constants.TYPE_DB_PROCESOR:
				table = constants.TABLE_MAP_DB_HOSTS
			dbm.open(table, db.DB_CREATE, db.DB_BTREE, sMode='w')
			c = dbm.cursor()
			appTuple = c.set(sApp)
			bPut = False
			if appTuple:
				while appTuple:
					print appTuple
					sApp, sData = appTuple
					sHostTarget, iStatus = json.loads(sData)
					if sHost == sHostTarget:
						tupleNew = (sHost, constants.STATUS_DOWN)
						sData = json.dumps(tupleNew)
						print 'sData->', sData
						c.put(sApp, sData, db.DB_CURRENT)
						bPut = True
					appTuple = c.next_dup()
			if not bPut:
				dataTuple = (sHost, constants.STATUS_DOWN)
				sData = json.dumps(dataTuple)
				dbm.put(sApp, sData)
			c.close()
			dbm.close()
	def deleteHost(self, sApp, sHost, sType):
		"""Deletes host for application and type of server in the cloud.
		@param sApp : String: Application
		@param sHost : String: Host
		@param sType : String : Type of host, processor or data processor."""
		if sType == constants.TYPE_PROCESSOR:
			tuple = config.MappingHostTuple
		elif sType == constants.TYPE_DB_PROCESOR:
			tuple = config.MappingDbHostTuple
		for sHostMap in tuple:
			print 'HostMap =>', sHostMap
			dbm = Dbm(sHostMap, config.OctopusDict['user'], config.OctopusDict['password'], config.OctopusDict['environment'])
			if sType == constants.TYPE_PROCESSOR:
				table = constants.TABLE_MAP_HOSTS
			elif sType == constants.TYPE_DB_PROCESOR:
				table = constants.TABLE_MAP_DB_HOSTS
			dbm.open(table, db.DB_CREATE, db.DB_BTREE, sMode='w')
			c = dbm.cursor()
			appTuple = c.set(sApp)
			if appTuple:
				while appTuple:
					sApp, sData = appTuple
					sHostTarget, iStatus = json.loads(sData)
					if sHostTarget == sHost:
						c.delete()
					appTuple = c.next_dup()
			c.close()
			dbm.close()
	def getHosts(self, sApp, sType):
		"""Lists hosts for application and type
		@param sApp : String : Application
		@param sType : String: Type of host
		@return: list : List : List of tuples (sApp -> (sHost, iStatus)) """
		if sType == constants.TYPE_PROCESSOR:
			tuple = config.MappingHostTuple
		elif sType == constants.TYPE_DB_PROCESOR:
			tuple = config.MappingDbHostTuple
		sHostMap = random.choice(tuple)
		print 'HostMap =>', sHostMap
		dbm = Dbm(sHostMap, config.OctopusDict['user'], config.OctopusDict['password'], config.OctopusDict['environment'])
		if sType == constants.TYPE_PROCESSOR:
			table = constants.TABLE_MAP_HOSTS
		elif sType == constants.TYPE_DB_PROCESOR:
			table = constants.TABLE_MAP_DB_HOSTS
		list = dbm.search(table, [sApp], 200, db.DB_BTREE, db.DB_CREATE)
		listNew = []
		for tuple in list:
			sApp, sData = tuple
			dataTuple = json.loads(sData)
			tupleNew = (sApp, dataTuple)
			listNew.append(tupleNew)
		return listNew
